﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;

namespace Us.Mil.Osd.Acq.Damir.Test
{
	public class ConstantExpressionRewriter : ExpressionVisitor
	{
		Expression root;
		IEnumerable<ConstantExpression> constants;
		Dictionary<Type, ConstantExpression> map;
		public ConstantExpressionRewriter(Expression root, IEnumerable<ConstantExpression> constants) {
			this.constants = constants;
			this.root = root;
			this.map = new Dictionary<Type, ConstantExpression>();
			foreach (ConstantExpression c in constants) {
				Type elementType = TypeHelper.GetElementType(c.Type);
				this.map.Add(elementType, c);
			}
		}

		public Expression Rewrite() {
			return this.Visit(this.root);
		}

		public override Expression Visit(Expression node) {
			return base.Visit(node);
		}

		protected override ElementInit VisitElementInit(ElementInit node) {
			return base.VisitElementInit(node);
		}

		protected override Expression VisitNew(NewExpression node) {
			Type elementType;
			if (this.IsQuery(node, out elementType)) {
				//LambdaExpression lambda = Expression.Lambda(node);
				//object instance = lambda.Compile().DynamicInvoke(new object[0]);
				//return Expression.Constant(instance);
				IQueryable replacement = ((System.Collections.IEnumerable)this.map[elementType].Value).AsQueryable();
				return Expression.Constant(replacement);
			}
			return base.VisitNew(node);
		}


		protected override Expression VisitConstant(ConstantExpression node) {
			Type elementType;
			if (this.IsQuery(node, out elementType)) {
				IQueryable replacement = ((System.Collections.IEnumerable)this.map[elementType].Value).AsQueryable();
				return Expression.Constant(replacement);
			}
			return base.VisitConstant(node);
		}
	}
}
